import React, { useCallback, useState, useRef, useEffect } from 'react';
import { View, TouchableOpacity, Image, Text, StyleSheet, Platform, ScrollView, Linking, Dimensions, ActivityIndicator } from 'react-native';
import { Video, ResizeMode, AVPlaybackStatus, VideoFullscreenUpdate } from 'expo-av';
import { MaterialIcons } from '@expo/vector-icons';
import { Audio } from 'expo-av';
import * as ScreenOrientation from 'expo-screen-orientation';
import { useTheme } from '../../components/theme/ThemeContext';
import { ArtworkResponse } from '../../utils/api/types';
import Slider from '@react-native-community/slider';
import { getFullURL, addTimestamp } from '../../utils/url';
import { useFocusEffect } from '@react-navigation/native';
import WebView from 'react-native-webview';

interface MediaPlayerProps {
  artwork: ArtworkResponse;
  onMediaStateChange?: (isPlaying: boolean) => void;
}

// 文件类型图标映射
const FILE_TYPE_ICONS = {
  'video': 'videocam',
  'audio': 'audiotrack',
  'image': 'image',
  'text': 'description',
  'code': 'code',
  'pdf': 'picture-as-pdf',
  'application': 'insert-drive-file',
} as const;

function MediaPlayer({ artwork, onMediaStateChange }: MediaPlayerProps) {
  const { theme } = useTheme();
  const [isPlaying, setIsPlaying] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [duration, setDuration] = useState(0);
  const [position, setPosition] = useState(0);
  const [volume, setVolume] = useState(1.0);
  const [isSeeking, setIsSeeking] = useState(false);
  const videoRef = useRef<Video>(null);
  const [sound, setSound] = useState<Audio.Sound>();
  
  // 使用 useMemo 缓存媒体URL
  const mediaUrl = React.useMemo(() => {
    return getFullURL(artwork.file_url);
  }, [artwork.file_url]);

  // 初始化音频系统
  useEffect(() => {
    const initAudio = async () => {
      try {
        await Audio.setAudioModeAsync({
          playsInSilentModeIOS: true,
          staysActiveInBackground: false,
          shouldDuckAndroid: true,
        });
      } catch (error) {
        console.error('音频系统初始化失败:', error);
      }
    };

    initAudio();
    return () => {
      if (sound) {
        sound.unloadAsync();
      }
    };
  }, []);

  // 格式化时间
  const formatTime = (milliseconds: number) => {
    const totalSeconds = Math.floor(milliseconds / 1000);
    const minutes = Math.floor(totalSeconds / 60);
    const seconds = totalSeconds % 60;
    return `${minutes}:${seconds.toString().padStart(2, '0')}`;
  };

  const handlePlaybackStatusUpdate = useCallback((status: AVPlaybackStatus) => {
    if (!status.isLoaded) {
      setIsLoading(true);
      return;
    }

    setIsLoading(false);
    if (!isSeeking) {
      setDuration(status.durationMillis || 0);
      setPosition(status.positionMillis || 0);
    }

    if (status.isPlaying !== isPlaying) {
      setIsPlaying(status.isPlaying);
      onMediaStateChange?.(status.isPlaying);
    }
  }, [isPlaying, isSeeking, onMediaStateChange]);

  const handlePlayPause = useCallback(async () => {
    try {
      if (artwork.file_type === 'audio') {
        if (!sound) {
          const { sound: newSound } = await Audio.Sound.createAsync(
            { uri: mediaUrl },
            { shouldPlay: true, volume: volume },
            handlePlaybackStatusUpdate
          );
          setSound(newSound);
          setIsPlaying(true);
        } else {
          const status = await sound.getStatusAsync();
          if (status.isLoaded) {
            if (status.isPlaying) {
              await sound.pauseAsync();
              setIsPlaying(false);
            } else {
              await sound.playAsync();
              setIsPlaying(true);
            }
          }
        }
      } else if (artwork.file_type === 'video' && videoRef.current) {
        const status = await videoRef.current.getStatusAsync();
        if (!status.isLoaded) return;

        if (status.isPlaying) {
          await videoRef.current.pauseAsync();
        } else {
          await videoRef.current.playAsync();
        }
      }
    } catch (error) {
      console.error('媒体播放控制错误:', error);
    }
  }, [artwork.file_type, mediaUrl, sound, volume]);

  // 处理进度条拖动开始
  const handleSeekStart = useCallback(() => {
    setIsSeeking(true);
  }, []);

  // 处理进度条拖动结束
  const handleSeekComplete = useCallback(async (value: number) => {
    try {
      if (artwork.file_type === 'audio' && sound) {
        await sound.setPositionAsync(value);
      } else if (artwork.file_type === 'video' && videoRef.current) {
        await videoRef.current.setPositionAsync(value);
      }
      setPosition(value);
      setIsSeeking(false);
    } catch (error) {
      console.error('设置进度失败:', error);
    }
  }, [artwork.file_type, sound]);

  // 处理音量调节
  const handleVolumeChange = useCallback(async (value: number) => {
    try {
      if (artwork.file_type === 'audio' && sound) {
        await sound.setVolumeAsync(Math.max(0, Math.min(1, value)));
      } else if (artwork.file_type === 'video' && videoRef.current) {
        await videoRef.current.setVolumeAsync(Math.max(0, Math.min(1, value)));
      }
      setVolume(value);
    } catch (error) {
      console.error('设置音量失败:', error);
    }
  }, [artwork.file_type, sound]);

  // 加载媒体
  useEffect(() => {
    let isMounted = true;

    const loadMedia = async () => {
      try {
        if (artwork.file_type === 'audio') {
          const { sound: newSound } = await Audio.Sound.createAsync(
            { uri: mediaUrl },
            { shouldPlay: false, volume: volume },
            handlePlaybackStatusUpdate
          );
          if (isMounted) {
            setSound(newSound);
            setIsLoading(false);
          }
        } else if (artwork.file_type === 'video' && videoRef.current) {
          await videoRef.current.loadAsync(
            { uri: mediaUrl },
            { shouldPlay: false, volume: volume },
            false
          );
          if (isMounted) {
            setIsLoading(false);
          }
        }
      } catch (error) {
        console.error('媒体加载错误:', error);
      }
    };
    
    loadMedia();

    return () => {
      isMounted = false;
      if (sound) {
        sound.unloadAsync();
      }
      if (videoRef.current) {
        videoRef.current.unloadAsync();
      }
    };
  }, [mediaUrl, volume, artwork.file_type]);

  // 停止播放
  const stopPlayback = useCallback(async () => {
    try {
      if (artwork.file_type === 'audio' && sound) {
        await sound.stopAsync();
        await sound.unloadAsync();
        setSound(undefined);
      } else if (artwork.file_type === 'video' && videoRef.current) {
        await videoRef.current.stopAsync();
        await videoRef.current.unloadAsync();
      }
      setIsPlaying(false);
      setPosition(0);
    } catch (error) {
      console.error('停止播放失败:', error);
    }
  }, [artwork.file_type, sound]);

  // 处理页面焦点变化
  useFocusEffect(
    useCallback(() => {
      return () => {
        stopPlayback();
      };
    }, [stopPlayback])
  );

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      stopPlayback();
    };
  }, [stopPlayback]);

  // 获取文件类型图标
  const getFileTypeIcon = useCallback((fileType: string) => {
    const type = fileType.split('/')[0];
    return FILE_TYPE_ICONS[type as keyof typeof FILE_TYPE_ICONS] || 'insert-drive-file';
  }, []);

  // 渲染文本预览
  const renderTextPreview = () => (
    <View style={[styles.previewContainer, { backgroundColor: theme.colors.card }]}>
      <WebView
        source={{ uri: mediaUrl }}
        style={styles.webView}
        startInLoadingState={true}
        renderLoading={() => (
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color={theme.colors.primary} />
          </View>
        )}
      />
    </View>
  );

  // 渲染PDF预览
  const renderPDFPreview = () => (
    <View style={[styles.previewContainer, { backgroundColor: theme.colors.card }]}>
      <WebView
        source={{ uri: mediaUrl }}
        style={styles.webView}
        startInLoadingState={true}
        renderLoading={() => (
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color={theme.colors.primary} />
          </View>
        )}
      />
    </View>
  );

  // 渲染图片预览
  const renderImagePreview = () => (
    <View style={[styles.previewContainer, { backgroundColor: theme.colors.card }]}>
      <Image
        source={{ uri: mediaUrl }}
        style={styles.image}
        resizeMode="contain"
        onLoadStart={() => setIsLoading(true)}
        onLoadEnd={() => setIsLoading(false)}
      />
      {isLoading && (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color={theme.colors.primary} />
        </View>
      )}
    </View>
  );

  // 渲染通用文件信息
  const renderFileInfo = () => {
    const fileType = artwork.file_type.split('/')[1] || artwork.file_type;
    const icon = getFileTypeIcon(artwork.file_type);
    
    return (
      <View style={[styles.fileInfoContainer, { backgroundColor: theme.colors.card }]}>
        <MaterialIcons name={icon} size={48} color={theme.colors.primary} />
        <Text style={[styles.fileTypeText, { color: theme.colors.text }]}>
          {fileType.toUpperCase()}
        </Text>
        <TouchableOpacity
          style={[styles.downloadButton, { backgroundColor: theme.colors.primary }]}
          onPress={() => Linking.openURL(mediaUrl)}
        >
          <MaterialIcons name="file-download" size={24} color="#fff" />
          <Text style={styles.downloadButtonText}>下载文件</Text>
        </TouchableOpacity>
      </View>
    );
  };

  const renderMedia = () => {
    const fileType = artwork.file_type.split('/')[0];

    switch (fileType) {
      case 'image':
        return renderImagePreview();
        
      case 'video':
        return (
          <View style={[styles.mediaContainer, { backgroundColor: theme.colors.background }]}>
            <View style={styles.videoContainer}>
              <Video
                ref={videoRef}
                source={{ uri: mediaUrl }}
                style={styles.video}
                resizeMode={ResizeMode.CONTAIN}
                isLooping
                shouldPlay={false}
                useNativeControls={false}
                onPlaybackStatusUpdate={handlePlaybackStatusUpdate}
                onError={(error) => console.error('视频播放错误:', error)}
                volume={volume}
              />
              {isLoading && (
                <View style={styles.loadingContainer}>
                  <ActivityIndicator size="large" color={theme.colors.primary} />
                </View>
              )}
            </View>
            {renderControls()}
          </View>
        );
      
      case 'audio':
        return (
          <View style={[styles.mediaContainer, { backgroundColor: theme.colors.background }]}>
            <View style={[styles.audioContainer, { backgroundColor: theme.colors.card }]}>
              <MaterialIcons name="audiotrack" size={48} color={theme.colors.primary} />
            </View>
            {renderControls()}
          </View>
        );
      
      case 'text':
      case 'code':
        return renderTextPreview();
      
      case 'application':
        if (artwork.file_type.includes('pdf')) {
          return renderPDFPreview();
        }
        return renderFileInfo();
      
      default:
        return renderFileInfo();
    }
  };

  // 抽取控制栏渲染逻辑
  const renderControls = () => {
    if (!['video', 'audio'].includes(artwork.file_type.split('/')[0])) {
      return null;
    }

    return (
      <View style={[styles.controlsContainer, { backgroundColor: theme.colors.card }]}>
        <View style={styles.controlsRow}>
          <TouchableOpacity onPress={handlePlayPause} style={styles.playButton}>
            <MaterialIcons
              name={isPlaying ? "pause" : "play-arrow"}
              size={32}
              color={theme.colors.text}
            />
          </TouchableOpacity>
          
          <View style={styles.progressContainer}>
            <Slider
              style={styles.progressBar}
              value={position}
              minimumValue={0}
              maximumValue={duration}
              onSlidingStart={handleSeekStart}
              onSlidingComplete={handleSeekComplete}
              minimumTrackTintColor={theme.colors.primary}
              maximumTrackTintColor={theme.colors.border}
              thumbTintColor={theme.colors.primary}
            />
            <Text style={[styles.timeText, { color: theme.colors.text }]}>
              {formatTime(position)} / {formatTime(duration)}
            </Text>
          </View>

          <View style={styles.volumeContainer}>
            <TouchableOpacity 
              onPress={() => handleVolumeChange(volume === 0 ? 1 : 0)}
              style={styles.volumeButton}
            >
              <MaterialIcons 
                name={volume === 0 ? "volume-mute" : "volume-up"} 
                size={24} 
                color={theme.colors.text} 
              />
            </TouchableOpacity>
            <Slider
              style={styles.volumeSlider}
              value={volume}
              minimumValue={0}
              maximumValue={1}
              step={0.05}
              onValueChange={handleVolumeChange}
              minimumTrackTintColor={theme.colors.primary}
              maximumTrackTintColor={theme.colors.border}
              thumbTintColor={theme.colors.primary}
            />
          </View>
        </View>
      </View>
    );
  };

  return renderMedia();
}

const styles = StyleSheet.create({
  mediaContainer: {
    width: '100%',
  },
  videoContainer: {
    width: '100%',
    aspectRatio: 16 / 9,
    position: 'relative',
    backgroundColor: '#000',
  },
  audioContainer: {
    width: '100%',
    aspectRatio: 16 / 9,
    justifyContent: 'center',
    alignItems: 'center',
    borderTopLeftRadius: 8,
    borderTopRightRadius: 8,
  },
  video: {
    width: '100%',
    height: '100%',
  },
  loadingContainer: {
    ...StyleSheet.absoluteFillObject,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0,0,0,0.3)',
  },
  controlsContainer: {
    width: '100%',
    padding: 8,
    borderBottomLeftRadius: 8,
    borderBottomRightRadius: 8,
  },
  controlsRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  playButton: {
    padding: 8,
  },
  progressContainer: {
    flex: 1,
  },
  progressBar: {
    height: 32,
  },
  timeText: {
    fontSize: 12,
    textAlign: 'center',
    marginTop: -8,
  },
  volumeContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    width: 120,
    gap: 4,
  },
  volumeButton: {
    padding: 4,
  },
  volumeSlider: {
    flex: 1,
    height: 32,
  },
  previewContainer: {
    width: '100%',
    aspectRatio: 16 / 9,
    borderRadius: 8,
    overflow: 'hidden',
  },
  webView: {
    flex: 1,
  },
  fileInfoContainer: {
    width: '100%',
    aspectRatio: 16 / 9,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 8,
    padding: 16,
    gap: 16,
  },
  fileTypeText: {
    fontSize: 16,
    fontWeight: 'bold',
  },
  downloadButton: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 12,
    borderRadius: 8,
    gap: 8,
  },
  downloadButtonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '600',
  },
  image: {
    width: '100%',
    height: '100%',
    backgroundColor: 'transparent',
  },
});

export default React.memo(MediaPlayer); 